import ArgumentType from './extension-support/argument-type';
import BlockType from './extension-support/block-type';
import blockIconURI from './image/icon.svg';

class DeepSeekAIExtension {
    constructor(runtime) {
        this.runtime = runtime;
        // 直接内置API密钥
        this.apiKey = 'sk-cb4989163c2944cbacb444d3fafef359';
        this.baseUrl = 'https://api.deepseek.com/v1';
        this.model = 'deepseek-chat';
        this.pendingRequests = {};
        this.requestId = 0;
        this.requestTimeouts = {}; // 存储超时处理器
        this.isDebugging = true; // 启用调试模式
        this.logs = []; // 日志存储数组
        this.maxLogs = 100; // 最大日志条数
        this.timeoutDuration = 60000; // 超时时间设置为60秒
        
        // 预设系统角色及其对应的提示
        this.systemRoles = {
            '你是一个有用的AI助手': '你是一个有用的AI助手，尽可能准确地回答用户的问题。',
            '你是一个代码专家': '你是一个代码专家，擅长编程和解决技术问题。提供详细的代码示例并解释代码原理。',
            '你是一个数学老师': '你是一个数学老师，擅长解释数学概念和解决数学问题。提供详细的解题步骤。',
            '你是一个创意顾问': '你是一个创意顾问，帮助用户拓展思路，提供创新的想法和建议。',
            '你是一个科学家': '你是一个科学家，专注于解释科学概念、现象和原理。提供准确的科学知识。',
            '你是一个故事作家': '你是一个故事作家，可以创作有趣的故事，或者根据用户的要求继续发展故事情节。'
        };
        
        // 当前系统角色，默认为助手
        this.currentSystemRole = '你是一个有用的AI助手';
    }

    getInfo() {
        return {
            name: 'DeepSeek AI',
            color: '#4B89DC',
            blockIconURI: blockIconURI,
            blocks: [
                {
                    opcode: 'askDeepSeek',
                    blockType: BlockType.REPORTER,
                    text: '向 DeepSeek AI 提问 [QUESTION]',
                    arguments: {
                        QUESTION: {
                            type: ArgumentType.STRING,
                            defaultValue: '你好，请介绍一下你自己'
                        }
                    }
                },
                {
                    opcode: 'setSystemRole',
                    blockType: BlockType.COMMAND,
                    text: '设置 AI 角色为 [ROLE]',
                    arguments: {
                        ROLE: {
                            type: ArgumentType.STRING,
                            menu: 'systemRoleMenu',
                            defaultValue: '你是一个有用的AI助手'
                        }
                    }
                },
                {
                    opcode: 'getCurrentRole',
                    blockType: BlockType.REPORTER,
                    text: '当前 AI 角色',
                    disableMonitor: false
                },
                {
                    opcode: 'setCustomSystemPrompt',
                    blockType: BlockType.COMMAND,
                    text: '设置自定义角色提示 [PROMPT]',
                    arguments: {
                        PROMPT: {
                            type: ArgumentType.STRING,
                            defaultValue: '你是一个专业的讲解员，善于用通俗易懂的语言解释复杂概念'
                        }
                    }
                },
                {
                    opcode: 'setModel',
                    blockType: BlockType.COMMAND,
                    text: '设置 DeepSeek 模型 [MODEL]',
                    arguments: {
                        MODEL: {
                            type: ArgumentType.STRING,
                            menu: 'modelMenu',
                            defaultValue: 'deepseek-chat'
                        }
                    }
                },
                {
                    opcode: 'setTimeout',
                    blockType: BlockType.COMMAND,
                    text: '设置请求超时时间 [TIMEOUT] 秒',
                    arguments: {
                        TIMEOUT: {
                            type: ArgumentType.NUMBER,
                            defaultValue: 60
                        }
                    }
                },
                {
                    opcode: 'getLastLog',
                    blockType: BlockType.REPORTER,
                    text: '获取最近的日志',
                    disableMonitor: false
                },
                {
                    opcode: 'getLastError',
                    blockType: BlockType.REPORTER,
                    text: '获取最近的错误信息',
                    disableMonitor: false
                },
                {
                    opcode: 'getLastRequest',
                    blockType: BlockType.REPORTER,
                    text: '获取最近的请求详情',
                    disableMonitor: false
                },
                {
                    opcode: 'clearLogs',
                    blockType: BlockType.COMMAND,
                    text: '清除所有日志',
                }
            ],
            menus: {
                modelMenu: ['deepseek-chat', 'deepseek-reasoner'],
                systemRoleMenu: {
                    acceptReporters: false,
                    items: Object.keys(this.systemRoles)
                }
            }
        };
    }

    setModel(args) {
        this.model = args.MODEL;
        this._log(`模型已设置为: ${this.model}`, 'info');
        return `已设置模型为 ${this.model}`;
    }
    
    setTimeout(args) {
        // 确保超时时间是有效的正数
        const timeout = Math.max(10, Number(args.TIMEOUT) || 60);
        this.timeoutDuration = timeout * 1000; // 转换为毫秒
        this._log(`请求超时时间已设置为: ${timeout}秒`, 'info');
        return `已设置超时时间为${timeout}秒`;
    }
    
    setSystemRole(args) {
        const role = args.ROLE;
        if (this.systemRoles[role]) {
            this.currentSystemRole = role;
            this._log(`AI角色已设置为: ${role}`, 'info');
            return `已设置AI角色为 ${role}`;
        } else {
            this._log(`未知角色: ${role}`, 'error');
            return `未知角色: ${role}`;
        }
    }
    
    getCurrentRole() {
        return this.currentSystemRole;
    }
    
    setCustomSystemPrompt(args) {
        const customPrompt = String(args.PROMPT || '').trim();
        if (customPrompt) {
            // 添加自定义角色
            const roleName = '自定义角色';
            this.systemRoles[roleName] = customPrompt;
            this.currentSystemRole = roleName;
            this._log(`已设置自定义角色提示: ${customPrompt.substring(0, 30)}...`, 'info');
            return `已设置自定义角色提示`;
        } else {
            this._log('自定义角色提示不能为空', 'error');
            return '自定义角色提示不能为空';
        }
    }

    async askDeepSeek(args) {
        const question = args.QUESTION;
        // 获取当前选择的系统角色对应的提示
        const systemPrompt = this.systemRoles[this.currentSystemRole] || '你是一个有用的AI助手';
        return await this._callDeepSeekAPI(question, systemPrompt);
    }
    
    getLastLog() {
        if (this.logs.length === 0) {
            return "暂无日志";
        }
        return this.logs[this.logs.length - 1].message;
    }
    
    getLastError() {
        for (let i = this.logs.length - 1; i >= 0; i--) {
            if (this.logs[i].type === 'error') {
                return this.logs[i].message;
            }
        }
        return "暂无错误";
    }
    
    getLastRequest() {
        for (let i = this.logs.length - 1; i >= 0; i--) {
            if (this.logs[i].message.includes('请求ID:')) {
                return this.logs[i].message;
            }
        }
        return "暂无请求记录";
    }
    
    clearLogs() {
        this.logs = [];
        return "所有日志已清除";
    }

    _log(message, type = 'info') {
        const timestamp = new Date().toLocaleString();
        const logEntry = {
            timestamp,
            type,
            message
        };
        
        // 添加到日志数组
        this.logs.push(logEntry);
        
        // 限制日志大小
        if (this.logs.length > this.maxLogs) {
            this.logs.shift(); // 移除最旧的日志
        }
        
        // 同时输出到控制台
        if (this.isDebugging) {
            if (type === 'error') {
                console.error(`[DeepSeek ${timestamp}] ${message}`);
            } else {
                console.log(`[DeepSeek ${timestamp}] ${message}`);
            }
        }
    }

    async _callDeepSeekAPI(question, systemPrompt) {
        if (!this.apiKey) {
            this._log('请先设置API密钥', 'error');
            return '请先设置API密钥';
        }

        // 清理输入参数
        question = String(question || '').trim();
        systemPrompt = String(systemPrompt || '').trim();
        
        if (!question) {
            this._log('问题不能为空', 'error');
            return '问题不能为空';
        }

        this._log(`准备调用API: 模型=${this.model}, 问题长度=${question.length}字符`, 'info');
        this._log(`使用系统提示: ${systemPrompt.substring(0, 50)}...`, 'info');

        try {
            const requestId = this._getNextRequestId();
            
            // 严格按照DeepSeek官方示例构建请求
            const payload = {
                model: this.model,
                messages: [
                    { role: 'system', content: systemPrompt },
                    { role: 'user', content: question }
                ],
                stream: false,
                max_tokens: 2000  // 添加最大token限制，避免响应过长
            };
            
            this._log(`请求ID: ${requestId}, 请求负载: ${JSON.stringify(payload).substring(0, 100)}...`, 'info');
            
            // 创建一个Promise来处理异步请求
            return new Promise((resolve, reject) => {
                this.pendingRequests[requestId] = { resolve, reject };
                
                // 使用类中定义的超时时间
                this._log(`设置请求超时: ${this.timeoutDuration/1000}秒`, 'info');
                this.requestTimeouts[requestId] = setTimeout(() => {
                    if (this.pendingRequests[requestId]) {
                        const timeoutMessage = `请求超时：DeepSeek API 响应时间超过 ${this.timeoutDuration/1000} 秒，请稍后再试或调整超时设置`;
                        this._log(`请求 ${requestId} 超时`, 'error');
                        this.pendingRequests[requestId].resolve(timeoutMessage);
                        delete this.pendingRequests[requestId];
                        delete this.requestTimeouts[requestId];
                    }
                }, this.timeoutDuration); // 使用可配置的超时时间
                
                // 确保API密钥格式正确
                const apiKey = String(this.apiKey).trim();
                
                // 更新请求URL和请求头，完全按照DeepSeek文档
                const requestUrl = `${this.baseUrl}/chat/completions`;
                
                this._log(`发送请求到: ${requestUrl}`, 'info');
                
                // 使用XMLHttpRequest替代fetch，提高兼容性
                const xhr = new XMLHttpRequest();
                xhr.open('POST', requestUrl, true);
                xhr.setRequestHeader('Content-Type', 'application/json');
                xhr.setRequestHeader('Authorization', `Bearer ${apiKey}`);
                
                xhr.onreadystatechange = () => {
                    if (xhr.readyState === 4) { // 请求完成
                        // 清除超时定时器
                        if (this.requestTimeouts[requestId]) {
                            clearTimeout(this.requestTimeouts[requestId]);
                            delete this.requestTimeouts[requestId];
                        }
                        
                        this._log(`收到响应: 状态=${xhr.status}, 响应长度=${xhr.responseText ? xhr.responseText.length : 0}`, xhr.status >= 200 && xhr.status < 300 ? 'info' : 'error');
                        
                        if (xhr.status >= 200 && xhr.status < 300) {
                            try {
                                const data = JSON.parse(xhr.responseText);
                                this._log(`响应数据: ${JSON.stringify(data).substring(0, 100)}...`, 'info');
                                
                                if (!data.choices || !data.choices[0] || !data.choices[0].message) {
                                    throw new Error('API返回的数据格式不正确');
                                }
                                const result = data.choices[0].message.content;
                                this._log(`获取到的回答: ${result.substring(0, 50)}...`, 'info');
                                
                                if (this.pendingRequests[requestId]) {
                                    this.pendingRequests[requestId].resolve(result);
                                    delete this.pendingRequests[requestId];
                                }
                            } catch (error) {
                                const errorMessage = `解析API响应出错: ${error.message}`;
                                this._log(errorMessage, 'error');
                                if (this.pendingRequests[requestId]) {
                                    this.pendingRequests[requestId].resolve(errorMessage);
                                    delete this.pendingRequests[requestId];
                                }
                            }
                        } else {
                            let errorMessage = '';
                            if (xhr.status === 401) {
                                errorMessage = `授权失败(401)：API密钥无效或格式错误，请检查API密钥是否正确`;
                                this._log(`API密钥: ${apiKey.substring(0, 5)}...${apiKey.substring(apiKey.length - 5)}`, 'error');
                            } else if (xhr.status === 429) {
                                errorMessage = `请求过多(429)：超过API调用限制，请稍后再试`;
                            } else if (xhr.status === 503) {
                                errorMessage = `服务不可用(503)：DeepSeek服务器暂时不可用，请稍后再试`;
                            } else {
                                errorMessage = `HTTP错误，状态码: ${xhr.status}`;
                                try {
                                    const errorResponse = JSON.parse(xhr.responseText);
                                    this._log(`错误响应: ${JSON.stringify(errorResponse)}`, 'error');
                                } catch (e) {
                                    this._log(`无法解析错误响应: ${xhr.responseText}`, 'error');
                                }
                            }
                            
                            this._log(errorMessage, 'error');
                            
                            if (this.pendingRequests[requestId]) {
                                this.pendingRequests[requestId].resolve(errorMessage);
                                delete this.pendingRequests[requestId];
                            }
                        }
                    }
                };
                
                xhr.onerror = (error) => {
                    // 清除超时定时器
                    if (this.requestTimeouts[requestId]) {
                        clearTimeout(this.requestTimeouts[requestId]);
                        delete this.requestTimeouts[requestId];
                    }
                    
                    const errorMessage = `网络错误：无法连接到DeepSeek服务器，请检查网络连接`;
                    this._log(`请求错误: ${errorMessage}`, 'error');
                    this._log(`错误详情: ${JSON.stringify(error)}`, 'error');
                    
                    if (this.pendingRequests[requestId]) {
                        this.pendingRequests[requestId].resolve(errorMessage);
                        delete this.pendingRequests[requestId];
                    }
                };
                
                // 发送请求
                try {
                    xhr.send(JSON.stringify(payload));
                    this._log(`请求已发送, ID: ${requestId}`, 'info');
                } catch (e) {
                    this._log(`发送请求失败: ${e.message}`, 'error');
                    if (this.pendingRequests[requestId]) {
                        this.pendingRequests[requestId].resolve(`发送请求失败: ${e.message}`);
                        delete this.pendingRequests[requestId];
                        
                        if (this.requestTimeouts[requestId]) {
                            clearTimeout(this.requestTimeouts[requestId]);
                            delete this.requestTimeouts[requestId];
                        }
                    }
                }
            });
        } catch (error) {
            const errorMessage = `调用DeepSeek API时出错: ${error.message}`;
            this._log(errorMessage, 'error');
            return errorMessage;
        }
    }

    _getNextRequestId() {
        return this.requestId++;
    }
}

module.exports = DeepSeekAIExtension;